home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter8 / isohex8_1 / isohex8_1.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-25  |  12.3 KB  |  500 lines

  1. /*****************************************************************************
  2. IsoHex8_1.cpp
  3. Ernest S. Pazera
  4. 24MAY2000
  5. Start a WIN32 Application Workspace, add in this file
  6. Needs ddraw.lib and dxguid.lib
  7. Needs GDICanvas.h/cpp
  8. Needs DDFuncs.h/cpp
  9. Needs winmm.lib and mmsystem.h
  10. *****************************************************************************/
  11.  
  12. //////////////////////////////////////////////////////////////////////////////
  13. //INCLUDES
  14. //////////////////////////////////////////////////////////////////////////////
  15. #define WIN32_LEAN_AND_MEAN  
  16.  
  17. #include <windows.h>   
  18. #include "GDICanvas.h"
  19. #include "ddraw.h"
  20. #include "DDFuncs.h"
  21. #include "mmsystem.h"
  22.  
  23. //////////////////////////////////////////////////////////////////////////////
  24. //DEFINES
  25. //////////////////////////////////////////////////////////////////////////////
  26. //name for our window class
  27. #define WINDOWCLASS "ISOHEX8"
  28. //title of the application
  29. #define WINDOWTITLE "IsoHex 8-1"
  30.  
  31. //////////////////////////////////////////////////////////////////////////////
  32. //PROTOTYPES
  33. //////////////////////////////////////////////////////////////////////////////
  34. bool Prog_Init();//game data initalizer
  35. void Prog_Loop();//main game loop
  36. void Prog_Done();//game clean up
  37.  
  38. //enumeration functions
  39. HRESULT WINAPI EnumModesCallbackCount(LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext);
  40. HRESULT WINAPI EnumModesCallbackList(LPDDSURFACEDESC2 lpDDSurfaceDesc,LPVOID lpContext);
  41.  
  42. //////////////////////////////////////////////////////////////////////////////
  43. //GLOBALS
  44. //////////////////////////////////////////////////////////////////////////////
  45. HINSTANCE hInstMain=NULL;//main application handle
  46. HWND hWndMain=NULL;//handle to our main window
  47. //IDirectDraw7 Pointer
  48. LPDIRECTDRAW7 lpdd=NULL;
  49. //display mode structure
  50. struct DisplayMode
  51. {
  52.     DWORD dwWidth;
  53.     DWORD dwHeight;
  54.     DWORD dwBPP;
  55. };
  56. //display mode enumeration variables
  57. DWORD dwDisplayModeCount=0;
  58. DisplayMode* DisplayModeList=NULL;
  59.  
  60. //gdicanvas
  61. CGDICanvas gdicBall;
  62.  
  63. //surfaces
  64. LPDIRECTDRAWSURFACE7 lpddsPrime=NULL;
  65. LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
  66. LPDIRECTDRAWSURFACE7 lpddsBall=NULL;
  67.  
  68. //clipper
  69. LPDIRECTDRAWCLIPPER lpddclip=NULL;
  70.  
  71. //size of the display
  72. DWORD dwDisplayWidth=0;
  73. DWORD dwDisplayHeight=0;
  74.  
  75. //position of the ball
  76. POINT ptBallPosition[2];
  77. POINT ptLastPosition[2][2];
  78. //velocity of the ball
  79. POINT ptBallVelocity[2];
  80.  
  81. //paused mode
  82. bool bPaused=false;
  83.  
  84. //////////////////////////////////////////////////////////////////////////////
  85. //WINDOWPROC
  86. //////////////////////////////////////////////////////////////////////////////
  87. LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  88. {
  89.     //which message did we get?
  90.     switch(uMsg)
  91.     {
  92.     case WM_ACTIVATEAPP:
  93.         {
  94.             if(wParam)
  95.             {
  96.                 if(bPaused)
  97.                 {
  98.                     //being activated
  99.                     bPaused=false;
  100.  
  101.                     //restore all surfaces
  102.                     lpdd->RestoreAllSurfaces();
  103.  
  104.                     //clear out back buffer
  105.                     DDBLTFX ddbltfx;
  106.                     DDBLTFX_ColorFill(&ddbltfx,0);
  107.                     lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);
  108.  
  109.                     //reload ball images
  110.                     LPDDS_ReloadFromFile(lpddsBall,"IsoHex6_4.bmp");
  111.                 }
  112.             }
  113.             else
  114.             {
  115.                 //being deactivated
  116.                 bPaused=true;
  117.             }
  118.         }break;
  119.     case WM_KEYDOWN:
  120.         {
  121.             //check for escape key
  122.             if(wParam==VK_ESCAPE)
  123.             {
  124.                 DestroyWindow(hWndMain);
  125.             }
  126.  
  127.             return(0);//handled message
  128.         }break;
  129.     case WM_DESTROY://the window is being destroyed
  130.         {
  131.  
  132.             //tell the application we are quitting
  133.             PostQuitMessage(0);
  134.  
  135.             //handled message, so return 0
  136.             return(0);
  137.  
  138.         }break;
  139.     case WM_PAINT://the window needs repainting
  140.         {
  141.             //a variable needed for painting information
  142.             PAINTSTRUCT ps;
  143.             
  144.             //start painting
  145.             HDC hdc=BeginPaint(hwnd,&ps);
  146.  
  147.             /////////////////////////////
  148.             //painting code would go here
  149.             /////////////////////////////
  150.  
  151.             //end painting
  152.             EndPaint(hwnd,&ps);
  153.                         
  154.             //handled message, so return 0
  155.             return(0);
  156.         }break;
  157.     }
  158.  
  159.     //pass along any other message to default message handler
  160.     return(DefWindowProc(hwnd,uMsg,wParam,lParam));
  161. }
  162.  
  163.  
  164. //////////////////////////////////////////////////////////////////////////////
  165. //WINMAIN
  166. //////////////////////////////////////////////////////////////////////////////
  167. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
  168. {
  169.     //assign instance to global variable
  170.     hInstMain=hInstance;
  171.  
  172.     //create window class
  173.     WNDCLASSEX wcx;
  174.  
  175.     //set the size of the structure
  176.     wcx.cbSize=sizeof(WNDCLASSEX);
  177.  
  178.     //class style
  179.     wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  180.  
  181.     //window procedure
  182.     wcx.lpfnWndProc=TheWindowProc;
  183.  
  184.     //class extra
  185.     wcx.cbClsExtra=0;
  186.  
  187.     //window extra
  188.     wcx.cbWndExtra=0;
  189.  
  190.     //application handle
  191.     wcx.hInstance=hInstMain;
  192.  
  193.     //icon
  194.     wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  195.  
  196.     //cursor
  197.     wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
  198.  
  199.     //background color
  200.     wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  201.  
  202.     //menu
  203.     wcx.lpszMenuName=NULL;
  204.  
  205.     //class name
  206.     wcx.lpszClassName=WINDOWCLASS;
  207.  
  208.     //small icon
  209.     wcx.hIconSm=NULL;
  210.  
  211.     //register the window class, return 0 if not successful
  212.     if(!RegisterClassEx(&wcx)) return(0);
  213.  
  214.     //create main window
  215.     hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
  216.  
  217.     //error check
  218.     if(!hWndMain) return(0);
  219.  
  220.     //if program initialization failed, then return with 0
  221.     if(!Prog_Init()) return(0);
  222.  
  223.     //message structure
  224.     MSG msg;
  225.  
  226.     //message pump
  227.     for(;;)    
  228.     {
  229.         //look for a message
  230.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  231.         {
  232.             //there is a message
  233.  
  234.             //check that we arent quitting
  235.             if(msg.message==WM_QUIT) break;
  236.             
  237.             //translate message
  238.             TranslateMessage(&msg);
  239.  
  240.             //dispatch message
  241.             DispatchMessage(&msg);
  242.         }
  243.  
  244.         //run main game loop
  245.         Prog_Loop();
  246.     }
  247.     
  248.     //clean up program data
  249.     Prog_Done();
  250.  
  251.     //return the wparam from the WM_QUIT message
  252.     return(msg.wParam);
  253. }
  254.  
  255. //////////////////////////////////////////////////////////////////////////////
  256. //INITIALIZATION
  257. //////////////////////////////////////////////////////////////////////////////
  258. bool Prog_Init()
  259. {
  260.     lpdd=LPDD_Create(hWndMain,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
  261.  
  262.     //enumerate the displaymodes
  263.     dwDisplayModeCount=0;
  264.  
  265.     lpdd->EnumDisplayModes(0,NULL,NULL,EnumModesCallbackCount);
  266.  
  267.     DisplayModeList=new DisplayMode[dwDisplayModeCount];
  268.     dwDisplayModeCount=0;
  269.  
  270.     lpdd->EnumDisplayModes(0,NULL,NULL,EnumModesCallbackList);
  271.  
  272.     //pick a display mode
  273.     DisplayMode TestMode;
  274.     TestMode.dwWidth=0;
  275.     TestMode.dwHeight=0;
  276.     TestMode.dwBPP=0;
  277.     DWORD index;
  278.     bool found=false;
  279.  
  280.     for(index=0;(index<dwDisplayModeCount);index++)
  281.     {
  282.         if(DisplayModeList[index].dwBPP==16)
  283.         {
  284.             if(DisplayModeList[index].dwWidth>TestMode.dwWidth)
  285.             {
  286.                 TestMode.dwWidth=DisplayModeList[index].dwWidth;
  287.                 TestMode.dwHeight=DisplayModeList[index].dwHeight;
  288.                 TestMode.dwBPP=DisplayModeList[index].dwBPP;
  289.                 found=true;
  290.             }
  291.         }
  292.     }
  293.  
  294.     if(!found)
  295.     {
  296.         return(false);
  297.     }
  298.  
  299.     //set the display mode
  300.     lpdd->SetDisplayMode(TestMode.dwWidth,TestMode.dwHeight,TestMode.dwBPP,0,0);
  301.     //keep display width and height in global variables
  302.     dwDisplayWidth=TestMode.dwWidth;
  303.     dwDisplayHeight=TestMode.dwHeight;
  304.  
  305.     //create the primary surface with a single back buffer
  306.     lpddsPrime=LPDDS_CreatePrimary(lpdd,1);
  307.  
  308.     //retrieve back buffer
  309.     lpddsBack=LPDDS_GetSecondary(lpddsPrime);
  310.  
  311.     //do an initial clearing out of the back buffer
  312.     DDBLTFX ddbltfx;
  313.     DDBLTFX_ColorFill(&ddbltfx,0);
  314.  
  315.     //do a color fill
  316.     lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  317.  
  318.     //create the region
  319.     HRGN hrgn=CreateRectRgn(0,0,dwDisplayWidth,dwDisplayHeight);
  320.  
  321.     //set up clipper
  322.     lpddclip=LPDDCLIP_Create(lpdd,hrgn);
  323.  
  324.     //delete region
  325.     DeleteObject(hrgn);
  326.  
  327.     //attach clipper
  328.     lpddsBack->SetClipper(lpddclip);
  329.  
  330.     //load in the ball image
  331.     gdicBall.Load(NULL,"IsoHex8_1.bmp");
  332.  
  333.     //create an offscreen surface to contain the ball
  334.     lpddsBall=LPDDS_LoadFromFile(lpdd,"IsoHex8_1.bmp");
  335.  
  336.     //create a black color key
  337.     LPDDS_SetSrcColorKey(lpddsBall,0);
  338.  
  339.     //initialize ball position and velocity
  340.     ptBallPosition[0].x=0;
  341.     ptBallPosition[0].y=0;
  342.     ptLastPosition[0][0].x=0;
  343.     ptLastPosition[0][0].y=0;
  344.     ptLastPosition[0][1].x=0;
  345.     ptLastPosition[0][1].y=0;
  346.     ptBallPosition[1].x=0;
  347.     ptBallPosition[1].y=0;
  348.     ptLastPosition[1][0].x=0;
  349.     ptLastPosition[1][0].y=0;
  350.     ptLastPosition[1][1].x=0;
  351.     ptLastPosition[1][1].y=0;
  352.  
  353.     ptBallVelocity[0].x=(rand()&7)+1;
  354.     ptBallVelocity[0].y=(rand()&7)+1;
  355.     ptBallVelocity[1].x=(rand()&7)+1;
  356.     ptBallVelocity[1].y=(rand()&7)+1;
  357.  
  358.  
  359.     return(true);//return success
  360. }
  361.  
  362. //////////////////////////////////////////////////////////////////////////////
  363. //CLEANUP
  364. //////////////////////////////////////////////////////////////////////////////
  365. void Prog_Done()
  366. {    
  367.     //clean up clipper
  368.     LPDDCLIP_Release(&lpddclip);
  369.  
  370.     //clean up ball surface
  371.     LPDDS_Release(&lpddsBall);
  372.         
  373.     //clean up primary surface(this will clean up the back buffer, also)
  374.     LPDDS_Release(&lpddsPrime);
  375.  
  376.     //clean up the dd pointer
  377.     LPDD_Release(&lpdd);
  378.  
  379.     //clean up gdicanvas
  380.     gdicBall.Destroy();
  381.  
  382.     //get rid of enumeration stuff
  383.     delete [] DisplayModeList;
  384. }
  385.  
  386. //////////////////////////////////////////////////////////////////////////////
  387. //MAIN GAME LOOP
  388. //////////////////////////////////////////////////////////////////////////////
  389. void Prog_Loop()
  390. {
  391.     //if paused, return without doing anything
  392.     if(bPaused) return;
  393.  
  394.     int index;
  395.  
  396.     for(index=0;index<2;index++)
  397.     {
  398.  
  399.     //set up rectangle for filling
  400.     RECT rcFill;
  401.     SetRect(&rcFill,ptLastPosition[index][0].x,ptLastPosition[index][0].y,ptLastPosition[index][0].x+gdicBall.GetWidth(),ptLastPosition[index][0].y+gdicBall.GetHeight());
  402.  
  403.     //set up a ddbltfx
  404.     DDBLTFX ddbltfx;
  405.     DDBLTFX_ColorFill(&ddbltfx,0);
  406.  
  407.     //blt the color fill to the back buffer
  408.     lpddsBack->Blt(&rcFill,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  409.     }
  410.  
  411.     for(index=0;index<2;index++)
  412.     {
  413.     //set up source and destination rects for blitting the ball
  414.     RECT rcSrc;
  415.     RECT rcDst;
  416.  
  417.     SetRect(&rcSrc,0,0,gdicBall.GetWidth(),gdicBall.GetHeight());
  418.     CopyRect(&rcDst,&rcSrc);
  419.     OffsetRect(&rcDst,ptBallPosition[index].x,ptBallPosition[index].y);
  420.  
  421.     //blit the ball
  422.     lpddsBack->Blt(&rcDst,lpddsBall,&rcSrc,DDBLT_WAIT | DDBLT_KEYSRC, NULL);
  423.  
  424.     //copy current position of ball to old position
  425.     ptLastPosition[index][0]=ptLastPosition[index][1];
  426.     ptLastPosition[index][1]=ptBallPosition[index];
  427.  
  428.     //move the ball
  429.     ptBallPosition[index].x+=ptBallVelocity[index].x;
  430.     ptBallPosition[index].y+=ptBallVelocity[index].y;
  431.  
  432.     //bounds checking
  433.     //left side
  434.     if(ptBallPosition[index].x<=0)
  435.     {
  436.         //change direction
  437.         ptBallVelocity[index].x=abs(ptBallVelocity[index].x);
  438.         //play sound
  439.         PlaySound("bounce.wav",NULL,SND_FILENAME | SND_ASYNC);
  440.     }
  441.     //top side
  442.     if(ptBallPosition[index].y<=0)
  443.     {
  444.         //change direction
  445.         ptBallVelocity[index].y=abs(ptBallVelocity[index].y);
  446.         //play sound
  447.         PlaySound("bounce.wav",NULL,SND_FILENAME | SND_ASYNC);
  448.     }
  449.     //right side
  450.     if(ptBallPosition[index].x>=(int)dwDisplayWidth-gdicBall.GetWidth())
  451.     {
  452.         //change direction
  453.         ptBallVelocity[index].x=-abs(ptBallVelocity[index].x);
  454.         //play sound
  455.         PlaySound("bounce.wav",NULL,SND_FILENAME | SND_ASYNC);
  456.     }
  457.     //bottom side
  458.     if(ptBallPosition[index].y>=(int)dwDisplayHeight-gdicBall.GetHeight())
  459.     {
  460.         //change direction
  461.         ptBallVelocity[index].y=-abs(ptBallVelocity[index].y);
  462.         //play sound
  463.         PlaySound("bounce.wav",NULL,SND_FILENAME | SND_ASYNC);
  464.     }
  465.     }
  466.     //flip surfaces
  467.     lpddsPrime->Flip(NULL,DDFLIP_WAIT);
  468. }
  469.  
  470. //enumeration-count
  471. HRESULT WINAPI EnumModesCallbackCount(
  472.   LPDDSURFACEDESC2 lpDDSurfaceDesc,  
  473.   LPVOID lpContext                   
  474. )
  475. {
  476.     //increment the count variable
  477.     dwDisplayModeCount++;
  478.  
  479.     //continue the enumeration
  480.     return(DDENUMRET_OK);
  481. }
  482.  
  483. //enumeration-list
  484. HRESULT WINAPI EnumModesCallbackList(
  485.   LPDDSURFACEDESC2 lpDDSurfaceDesc,  
  486.   LPVOID lpContext                   
  487. )
  488. {
  489.     //copy applicable information to the list
  490.     DisplayModeList[dwDisplayModeCount].dwWidth=lpDDSurfaceDesc->dwWidth;
  491.     DisplayModeList[dwDisplayModeCount].dwHeight=lpDDSurfaceDesc->dwHeight;
  492.     DisplayModeList[dwDisplayModeCount].dwBPP=lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
  493.  
  494.     //increment the count variable
  495.     dwDisplayModeCount++;
  496.  
  497.     //continue the enumeration
  498.     return(DDENUMRET_OK);
  499. }
  500.